home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / jcool01.zip / CHAR.C < prev    next >
C/C++ Source or Header  |  1992-08-11  |  14KB  |  403 lines

  1. //
  2. // Copyright (C) 1991 Texas Instruments Incorporated.
  3. //
  4. // Permission is granted to any individual or institution to use, copy, modify,
  5. // and distribute this software, provided that this complete copyright and
  6. // permission notice is maintained, intact, in all copies and supporting
  7. // documentation.
  8. //
  9. // Texas Instruments Incorporated provides this software "as is" without
  10. // express or implied warranty.
  11. //
  12. //
  13. // Created: MBN 04/04/89 -- Initial design and implementation
  14. // Updated: MBN 12/15/89 -- Made case-flag optional on is_equal, is_not_equal
  15. // Updated: LGO 01/05/90 -- Split into seperate files
  16. // Updated: MJF 05/22/90 -- Fixed is_eqaul to return properly
  17. // Updated: DLS 03/22/91 -- New lite version
  18. // Updated: JAM 08/11/92 -- removed DOS specifics, stdized #include
  19. //
  20.  
  21. #include <ctype.h>        // Include character processing macros
  22. #include <cool/char.h>        // Include char* specification header file
  23.  
  24. Boolean is_equal (const char* c1, const char* c2, Boolean case_flag) {
  25.   if (case_flag == SENSITIVE) {            // Case sensitive
  26.     for ( ; *c1 == *c2; c1++, c2++)        // For each character in string
  27.       if (*c1 == END_OF_STRING)            // If end of first string
  28.     return TRUE;                // Match found, return TRUE
  29.     return (*c1 == *c2) ? TRUE : FALSE;        // Return match result
  30.   }
  31.   else {                    // Case insensitive
  32.     for ( ; *c1 == *c2 || TO_UPPER (*c1) == TO_UPPER (*c2); c1++, c2++)
  33.       if (*c1 == END_OF_STRING)            // If end of first string
  34.     return TRUE;                // Match found, return TRUE
  35.     // Return match result
  36.     return (*c1 == *c2 || TO_UPPER (*c1) == TO_UPPER (*c2)) ? TRUE : FALSE;
  37.   }
  38. }
  39.  
  40.  
  41. Boolean is_not_equal (const char* c1, const char* c2, Boolean case_flag) {
  42.   return (!is_equal (c1, c2, case_flag));
  43. }
  44.  
  45.  
  46. Boolean is_equal_n (const char* c1, const char* c2, int n, Boolean case_flag) {
  47.   if (case_flag == SENSITIVE) {            // Case sensitive
  48.     for ( ; --n >= 0 && *c1 == *c2; c1++, c2++)    // For each character in string
  49.       if (*c1 == END_OF_STRING)            // If end of first string
  50.     return TRUE;                // Match found, return TRUE
  51.     return n<0;                         // Return match result
  52.   }
  53.   else {                    // Case insensitive
  54.     for ( ; --n >= 0 && *c1 == *c2 || TO_UPPER (*c1) == TO_UPPER (*c2);
  55.     c1++, c2++)
  56.       if (*c1 == END_OF_STRING)            // If end of first string
  57.     return TRUE;                // Match found, return TRUE
  58.     return n<0;                         // Return match result
  59.   }
  60. }
  61.  
  62.  
  63. Boolean is_ge (const char* c1, const char* c2, Boolean case_flag) {
  64.   if (case_flag == SENSITIVE) {            // Case sensitive
  65.     for (; *c1 == *c2; c1++, c2++)        // For each character in string
  66.       if (*c1 == END_OF_STRING)            // If end of first string
  67.     return TRUE;                // Match found, return TRUE
  68.     return (*c1 > *c2) ? TRUE : FALSE;        // Return match result
  69.   }
  70.   else {                    // Case insensitive
  71.     for (;*c1 == *c2 || TO_UPPER (*c1) == TO_UPPER (*c2); c1++, c2++)
  72.       if (*c1 == END_OF_STRING)            // If end of first string
  73.     return TRUE;                // Match found, return TRUE
  74.     // Return match result
  75.     return (TO_UPPER (*c1) > TO_UPPER (*c2)) ? TRUE : FALSE;
  76.   }
  77. }
  78.  
  79.  
  80. Boolean is_lt (const char* c1, const char* c2, Boolean case_flag) {
  81.   return (!is_ge (c1, c2, case_flag));
  82. }
  83.  
  84.  
  85. Boolean is_le (const char* c1, const char* c2, Boolean case_flag) {
  86.   if (case_flag == SENSITIVE) {            // Case sensitive
  87.     for (; *c1 == *c2; c1++, c2++)        // For each character in string
  88.       if (*c1 == END_OF_STRING)            // If end of first string
  89.     return TRUE;                // Match found, return TRUE
  90.     return (*c1 < *c2) ? TRUE : FALSE;        // Return match result
  91.   }
  92.   else {                    // Case insensitive
  93.     for (; *c1 == *c2 || TO_UPPER (*c1) == TO_UPPER (*c2); c1++, c2++) 
  94.       if (*c1 == END_OF_STRING)            // If end of first string
  95.     return TRUE;                // Match found, return TRUE
  96.     // Return match result
  97.     return (TO_UPPER (*c1) < TO_UPPER (*c2)) ? TRUE : FALSE;
  98.   }
  99. }
  100.  
  101.  
  102. Boolean is_gt (const char* c1, const char* c2, Boolean case_flag) {
  103.   return (!is_le (c1, c2, case_flag));
  104. }
  105.  
  106. // c_capitalize -- Capitalize all words in a string. A word is defined as
  107. //                 a sequence of characters separated by non-alphanumerics
  108. // Input:          Character string
  109. // Output:         Updated string
  110.  
  111. char* c_capitalize (char* s) {        // Capitalize each word in string
  112.   char* p = s;                // Point to beginning of string
  113.   for (;;) {                // Infinite loop
  114.     for (; *p && !isalnum(*p); p++);    // Skip to first alphanumeric
  115.     if (*p == END_OF_STRING)        // If end of string
  116.       return s;                // Return string
  117.     *p = TO_UPPER(*p);            // Convert character
  118.     while(*++p && isalnum (*p));    // Search for next word
  119.   }
  120. }
  121.  
  122.  
  123. // c_downcase -- Convert all alphabetical characters to lowercase
  124. // Input:        Character string
  125. // Output:       Updated string
  126.  
  127. char* c_downcase (char* s) {    // Convert entire string to lower case
  128.   char* p = s;            // Point to beginning of string
  129.   while (*p) {            // While there are still valid characters
  130.     if (isupper (*p))        // if this is upper case
  131.       *p = TO_LOWER (*p);    // convert to lowercase 
  132.     p++;            // Advance pointer
  133.   }
  134.   return s;            // Return reference to modified string
  135. }
  136.  
  137.  
  138.  
  139. // c_left_trim -- Removes any occurrence of the character(s) in "rem" from
  140. //                "str" that appear as a prefix to the string. The first
  141. //                non-matching character encountered terminates the remove
  142. //                operation and the rest of the string is copied intact.
  143. // Input:         Source string and token string
  144. // Output:        Modified string "str" (string modified in place)
  145.  
  146. char* c_left_trim (char* str, const char* rem) { // Trim prefix from string
  147.   char* result = str;
  148.   char* s;
  149.   register char c;
  150.   for (s=str; (c=*s) != END_OF_STRING; s++) {
  151.     register const char* r = rem;
  152.     register char t;
  153.     while ((t=*r++) != END_OF_STRING && t != c); // Scan for match
  154.     if (t == END_OF_STRING)             // If no match found
  155.       break;
  156.   }
  157.   if (s != result)                  // when characters trimed
  158.     while ((*result++ = *s++) != END_OF_STRING); // shift string down
  159.   return str;                      // Return pointer to string
  160. }
  161.  
  162.  
  163. // c_right_trim -- Removes any occurrence of the character(s) in "rem" from
  164. //                 "str" that appear as a suffix to the string. The first
  165. //                 non-matching character encountered terminates the remove
  166. //                 operation and the rest of the string is copied intact.
  167. // Input:          Source string and token string
  168. // Output:         Modified string "str" (string modified in place)
  169.  
  170. char* c_right_trim (char* str, const char* rem) { // Trim suffix from string
  171.   char* s = str + strlen(str) - 1;          // last character of str
  172.   for (; s >= str; s--) {
  173.     register const char* r = rem;
  174.     register char t;
  175.     register char c = *s;
  176.     while ((t=*r++) != END_OF_STRING && t != c); // Scan for match
  177.     if (t == END_OF_STRING)             // If no match found
  178.       break;
  179.   }
  180.   *(s+1) = END_OF_STRING;
  181.   return str;                      // Return pointer to string
  182. }
  183.  
  184.  
  185. // c_trim -- Removes any occurrence of the character(s) in "rem" from "str"
  186. // Input:    Source string and token string
  187. // Output:   Source string (string is modified in place)
  188.  
  189. char* c_trim (char* str, const char* rem) {    // Trim characters from string
  190.   char* s = str;
  191.   char* result = str;
  192.   register char c;
  193.   while ((c=*s++) != END_OF_STRING) {
  194.     register const char* r = rem;
  195.     register char t;
  196.     while ((t=*r++) != END_OF_STRING && t != c); // Scan for match
  197.     if (t == END_OF_STRING)             // If no match found
  198.       *result++ = c;
  199.   }
  200.   *result = END_OF_STRING;            // NULL terminate string
  201.   return str;                    // Return pointer to string
  202. }
  203.  
  204.  
  205. // c_upcase -- Convert all alphabetical characters to uppercase
  206. // Input:      Character string 
  207. // Output:     Updated string
  208. //
  209.  
  210. char* c_upcase (char* s) {    // Convert entire string to upper case
  211.   char* p = s;            // Point to beginning of string
  212.   while (*p) {            // While there are still valid characters
  213.     if (islower (*p))        // if this is lower case
  214.       *p = TO_UPPER (*p);    // convert to uppercase 
  215.     p++;            // Advance pointer
  216.   }
  217.   return s;            // Return reference to modified string
  218. }
  219.  
  220. // strfind -- finds the pattern in the source.  Sets start and
  221. // end accordingly and returns a pointer to the beginning of the
  222. // string found, or NULL.  Uses * to mean any number of any characters,
  223. // and ? to mean one of any character.  \? and \* are used in the 
  224. // pattern to look for the actual symbols ? and * in the source.
  225. // Finds the first occurance from the beginning of the source string.
  226. //
  227.  
  228.  
  229. const char* strfind (const char* string, const char* pattern,
  230.              long* start, long* end)
  231. {
  232.   const char* stringp = string;
  233.   const char* startp = string;
  234.   for (; *pattern != '\0'; pattern++, string++) {
  235.     if (*pattern == '\\') {            // Special case \* and \?
  236.       pattern++;
  237.       if (*pattern == '*' || *pattern == '?') {
  238.     if (*string != *pattern)
  239.       return NULL;
  240.       }
  241.       else if (*string != '\\')
  242.     return NULL;
  243.     }
  244.     else if (*pattern == '*') {
  245.       long endp;
  246.       pattern++;
  247.       if (*pattern == '\0')
  248.     goto match;
  249.       while (strfind(string, pattern, (long *)NULL, &endp) == NULL) {
  250.     if (*string++ == '\0')
  251.       return NULL;
  252.       }
  253.       startp = string;
  254.       string += endp;
  255.       goto match;
  256.     }
  257.     else if (*string == '\0')
  258.       return NULL;
  259.     else if ((*pattern != '?') && (*pattern != *string))
  260.       return NULL;
  261.   }
  262.   if (*string != '\0') return NULL;
  263.  match:                        // Match found
  264.   if (start != NULL) *start = startp - stringp;
  265.   if (end != NULL) *end = string - stringp;
  266.   return(startp);
  267. }
  268.  
  269.  
  270. // strrfind -- finds the pattern in the source.  Sets start and
  271. // end accordingly and returns a pointer to the beginning of the
  272. // string found, or NULL.  Uses * to mean any number of any characters,
  273. // and ? to mean one of any character.  \? and \* are used in the 
  274. // pattern to look for the actual symbols ? and * in the source.
  275. // Finds the last occurance from the end of the source string.
  276.  
  277.  
  278. static const char* _strrfind(const char* strstart,
  279.                  const char* string,
  280.                  const char* patstart,
  281.                  const char* pattern,
  282.                  long* end)
  283. {
  284.   const char* startp = string;
  285.   for (; pattern >= patstart; pattern--, string--) {
  286.     if (*pattern == '*') {        // '*' matches anything or nothing
  287.       --pattern;
  288.       if (pattern >= patstart && *pattern == '\\') { // Special case \*
  289.     if (string < strstart || *string != '*')
  290.       return NULL;
  291.       }
  292.       else {
  293.     const char* res;
  294.     if (pattern < patstart) {
  295.       string++;
  296.       goto match;
  297.     }
  298.     while ((res=_strrfind(strstart,string,patstart,pattern,end)) == NULL) {
  299.       if (--string < strstart)
  300.         return NULL;
  301.     }
  302.     startp = string;
  303.     string = res;
  304.     goto match;
  305.       }
  306.     }
  307.     else if (string < strstart)            // check end of string
  308.       return NULL;
  309.     else if (*pattern == '?') {            // '?' matches any character
  310.       if (pattern > patstart && *(pattern-1) == '\\') { // Special case \?
  311.     pattern--;
  312.     if (*string != '?')
  313.       return NULL;
  314.       }
  315.     }
  316.     else if (*pattern != *string)
  317.       return NULL;
  318.   }
  319.   if (++string != strstart) return NULL;
  320.  match:                        // Match found
  321.   *end = startp - strstart + 1;
  322.   return(string);
  323. }
  324.  
  325.  
  326. const char* strrfind (const char* string, const char* pattern,
  327.               long* start, long* end)
  328. {
  329.   long endp;
  330.   const char* res = _strrfind(string, string + strlen(string) - 1,
  331.                   pattern, pattern + strlen(pattern) - 1, &endp);
  332.   if (res != NULL) {
  333.     if (start != NULL) *start = res - string;
  334.     if (end != NULL) *end = endp;
  335.   }
  336.   return(res);
  337. }
  338.  
  339. // strndup -- creates a new string and copies everything between
  340. // zero and length of the given char* into it.  Returns the new
  341. // string.
  342. //
  343.  
  344. char* strndup (const char* s, long length) {
  345.   if (length<0) return(NULL);
  346.   char* ret = (char*) new char[length+1];
  347.   char* retp = ret;  
  348.   while(length-- > 0 && *s != END_OF_STRING)
  349.     *retp++ = *s++;
  350.   *retp = END_OF_STRING;
  351.   return(ret);
  352. }
  353.  
  354.  
  355. // strnremove -- removes everything between zero and end from 
  356. // the given string.  Returns a pointer to the new string.
  357.  
  358. char* strnremove (char* s, long end) {
  359.   int len = strlen(s);
  360.   if (end < 0 ) return(NULL);
  361.   if (end > len) end = len;
  362.   for(int ind=0; s[ind]=s[end]; ind++) end++;
  363.   return(s);
  364. }
  365.  
  366. //
  367. // strnyank -- the equivalent of doing a strndup and a strnremove.
  368. // Returns a char* to the copy of zero-end elements of the given string.
  369. // Modifies the given string by removing the zero-end elements.
  370. //
  371.  
  372. char* strnyank (char* s, long end) {
  373.   int len = strlen(s);
  374.   if (end>len) end=len;
  375.   long mark = end;
  376.   char* ret = (char*) new char[end+1];
  377.   if (end < 0) return(NULL);
  378.   for(int ind=0; ind <= len; ind++) {
  379.     if (ind<mark) ret[ind]=s[ind];
  380.     s[ind]=s[end];
  381.     end++;
  382.   }
  383.   ret[mark]=END_OF_STRING;
  384.   return(ret);
  385. }
  386.  
  387.  
  388. // reverse -- Reverse the order of the characters in char*
  389. // Input:     char* 
  390. // Output:    char* with character order reversed
  391.  
  392. void reverse (char* c) {        // Reverse the order of characters
  393.   int length = strlen (c);        // Number of characters in string
  394.   char temp;
  395.  
  396.   for (int i = 0, j = length-1;        // Counting from front and rear
  397.        i < length / 2; i++, j--) {    // until we reach the middle
  398.     temp = c[i];            // Save front character
  399.     c[i] = c[j];            // Switch with rear character
  400.     c[j] = temp;            // Copy new rear character
  401.   }
  402. }
  403.